package com.jt.www.admin.user.service.impl;


import com.alibaba.fastjson.JSON;
import com.jt.www.admin.market.service.MarketerInfoService;
import com.jt.www.admin.user.service.RegisterCustomerService;
import com.jt.www.dao.mapper.registerCustomer.RegisterCustomerMapper;
import com.jt.www.domain.dto.PolicyAgentDto;
import com.jt.www.domain.enums.common.parser.ReturnType;
import com.jt.www.domain.enums.common.parser.SaveType;
import com.jt.www.domain.enums.pc.MarketerChannelCodeEnum;
import com.jt.www.domain.enums.wxb.PromotionStatusEnum;
import com.jt.www.domain.po.MarketerInfoEntity;
import com.jt.www.domain.qo.MarketerInfoQO;
import com.jt.www.domain.vo.EmployeeVO;
import com.jt.www.domain.vo.PromotersVo;
import com.jt.www.domain.vo.RegisterCustomerVo;
import com.jt.www.model.registerCustomer.RegisterCustomer;
import com.jt.www.model.registerCustomer.vo.*;
import com.jt.www.model.remote.user.LoginResultVO;
import com.jt.www.model.reps.GenericDataResponse;
import com.jt.www.model.reps.GenericListResponse;
import com.jt.www.model.reps.GenericResponse;
import com.jt.www.model.vo.ParserResultPolicyAgentVo;
import com.jt.www.model.vo.PolicyAgentVo;
import com.jt.www.remote.ParserClient;
import com.jt.www.remote.UserClient;
import com.jt.www.remote.ins.InsClient;
import com.jt.www.remote.woxuebao.InsOrderClient;
import com.jt.www.util.DateUtils;
import com.jt.www.util.JsonUtil;
import com.jt.www.util.RedisUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.assertj.core.util.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class RegisterCustomerServiceImpl implements RegisterCustomerService {

    public static final Logger log = LoggerFactory.getLogger(RegisterCustomerServiceImpl.class);

    private final static String SYS_EDU_PC_CODE = "sys_edu_pc";
    private final static String SYS_EDU_MAN_CODE = "sys_edu_man";
    /**
     * 保单绑定推广人的
     */
    private final static String POLICY_AGENT_MODEL = "bdbdtgr";
    private static final String CHANNEL_CODE = "edu";
    /**
     * 单个服务器出单查询缓存失效时间
     */
    private static final long MANAGER_TIME_OUT = 60L;
    @Autowired
    private RegisterCustomerMapper registerCustomerMapper;
    @Autowired
    private MarketerInfoService marketerInfoService;
    @Autowired
    private UserClient userClient;
    @Autowired
    private InsClient insClient;
    @Autowired
    private ParserClient parserClient;
    @Autowired
    private InsOrderClient insOrderClient;

    //添加客户经理  与注册用户关联表
    @Override
    public ResponseEntity insertBinaryRegisterCustomer(String findCode, RegisterCustomer registerCustomer) {
        //判断传入参数是否完整
        if (StringUtils.isBlank(registerCustomer.getUserCode()) || StringUtils.isBlank(registerCustomer.getCustomerCode())) {
            return GenericDataResponse.errorWithMsg("参数传入不完整");
        }

        ResponseEntity<GenericDataResponse<RegisterCustomer>> checkValue = checkValidity(findCode, registerCustomer);
        if (GenericDataResponse.CODE_NG.equals(checkValue.getBody().getCode())) {
            return checkValue;
        }

        //添加到数据库
        registerCustomer.setPromotionStatus(PromotionStatusEnum.NORMAL.getStatus());
        registerCustomer.setStartTime(new Date());
        registerCustomer.setCreationTime(new Date());
        registerCustomer.setIsDeleted(false);

        if (registerCustomerMapper.insertSelective(registerCustomer) == 1) {
            log.info("{} 绑定推广关系 service 客户经理与客户关联成功 推广人userCode:{},用户账号:{},customerCode:{}",
                    findCode, registerCustomer.getUserCode(), registerCustomer.getCustomerAccount(), registerCustomer.getCustomerCode());
            return GenericDataResponse.okWithData("客户经理与客户关联成功");
        }
        return GenericDataResponse.errorWithMsg("客户经理与客户关联失败");
    }

    @Override
    public ResponseEntity<GenericListResponse<RegisterCustomerVo>> queryCustomers(String findCode, CustomerListParam customerListParam) throws Exception {

        Long count = registerCustomerMapper.queryCustomersCount(customerListParam);
        if (null == count || count <= 0) {
            return GenericListResponse.listNoCount(null);
        }
        List<RegisterCustomerVo> entities = registerCustomerMapper.queryCustomers(customerListParam);
        return GenericListResponse.listAndCount(entities, count);
    }

    @Override
    public ResponseEntity<GenericDataResponse<ManagerInfoVo>> queryPromotersInfo(String findCode, String userCode) {

        log.info("{} 获取推广人信息 service 开始", findCode);

        if (StringUtils.isBlank(userCode)) {

            log.info("{} 获取推广人信息 service 用户编码为空", findCode);

            return GenericDataResponse.errorWithMsg("用户编码为空", ManagerInfoVo.class);
        }

        RegisterCustomer promoterCustomer = new RegisterCustomer();
        promoterCustomer.setUserCode(userCode);
        ResponseEntity<GenericDataResponse<RegisterCustomer>> promoterCheckValue = checkValidity(findCode, promoterCustomer);

        //查询用户中心该推广人是否是合法推广人(公司员工)
        if (GenericDataResponse.CODE_OK.equals(promoterCheckValue.getBody().getCode())) {
            log.info("{} 获取推广人信息 service 该用户(userCode:{})为公司员工，自己为合法推广人!", findCode, userCode);

            return GenericDataResponse.okWithData(createManagerInfoByRegisterCustomer(findCode, promoterCheckValue.getBody().getData(), userCode));
        } else {
            log.info("{}userCode：{}不是公司员工!查询做为被推广人是否有被推广的相关信息!", findCode, userCode);
            Weekend<RegisterCustomer> managerWeekend = Weekend.of(RegisterCustomer.class);
            WeekendCriteria<RegisterCustomer, Object> managerCriteria = managerWeekend.weekendCriteria();
            managerCriteria.andEqualTo(RegisterCustomer::getCustomerCode, userCode);
            managerCriteria.andEqualTo(RegisterCustomer::getPromotionStatus, PromotionStatusEnum.NORMAL.getStatus());
            managerCriteria.andEqualTo(RegisterCustomer::getIsDeleted, false);

            List<RegisterCustomer> managers = registerCustomerMapper.selectByExample(managerWeekend);
            //如果不为空表示有正常的关系
            if (CollectionUtils.isNotEmpty(managers)) {
                log.info("{}userCode：{}做为被推广人有推广人相关信息!{}", findCode, userCode, JSON.toJSONString(managers));
                //兼容错误数据，有可能会出现同一个人多少推广的数据，找到第一个合法的推广人
                for (RegisterCustomer registerCustomer : managers) {
                    RegisterCustomer checkPromoter = new RegisterCustomer();
                    checkPromoter.setUserCode(registerCustomer.getUserCode());
                    ResponseEntity<GenericDataResponse<RegisterCustomer>> promoterResponse = checkValidity(findCode, checkPromoter);
                    log.info("{}userCode：{}检查该推广人是否依然合法!{}", findCode, userCode, JSON.toJSONString(registerCustomer));
                    //成功表示合法
                    if (GenericDataResponse.CODE_OK.equals(promoterResponse.getBody().getCode())) {
                        log.info("{}userCode：{}推广人依然合法,返回推广人信息!{}", findCode, userCode, JSON.toJSONString(registerCustomer));
                        //使用最新的合法推广人信息
                        ManagerInfoVo managerInfoVo = createManagerInfoByRegisterCustomer(findCode, registerCustomer, userCode);
                        return GenericDataResponse.okWithData(managerInfoVo);
                    }
                }
            }

        }
        //无合法推广人
        return GenericDataResponse.okWithData(null);
    }

    private ManagerInfoVo createManagerInfoByRegisterCustomer(String findCode, RegisterCustomer registerCustomer, String userCode) {
        ManagerInfoVo managerInfoVo = new ManagerInfoVo();
        managerInfoVo.setUserCode(userCode);
        managerInfoVo.setManagerUserCode(registerCustomer.getUserCode());
        managerInfoVo.setManagerName(registerCustomer.getManagerName());
        managerInfoVo.setManagerAccount(registerCustomer.getManagerAccount());
        managerInfoVo.setBranchCode(registerCustomer.getBranchCode());
        managerInfoVo.setBranchName(registerCustomer.getBranchName());
        //查询是否是营销员
        MarketerInfoQO marketerInfoQO = new MarketerInfoQO();
        marketerInfoQO.setUserCode(registerCustomer.getUserCode());
        List<MarketerInfoEntity> marketerInfoEntities = marketerInfoService.queryMarketerList(findCode, marketerInfoQO, false);
        if (marketerInfoEntities.size() > 0) {
            MarketerInfoEntity marketerInfoEntity = marketerInfoEntities.get(0);
            managerInfoVo.setChannelCode(MarketerChannelCodeEnum.getNewCodeByCode(marketerInfoEntity.getChannelCode()));
            managerInfoVo.setChannelName(marketerInfoEntity.getChannelName());
            managerInfoVo.setAddChannelCode(marketerInfoEntity.getAddChannelCode());
            managerInfoVo.setAddChannelName(marketerInfoEntity.getAddChannelName());
        }
        return managerInfoVo;
    }

    private ResponseEntity queryUserCenterByCode(String findCode, String userCode) {
        try {
            GenericListResponse<UserManagerResultVo> pvtUserResp = userClient.queryPvtUserInfo(null, null, userCode);
            if (pvtUserResp.getTotal() > 0) {
                log.info("{} 获取推广人信息 service 在用户中心查询到该账户信息 userCode:{}", findCode, userCode);
                UserManagerResultVo vo = pvtUserResp.getList().get(0);
                if ("0".equals(vo.getStatus())) {

                    log.info("{} 获取推广人信息 service 在用户中心查询到该账户信息,该账户状态为已停用 userCode:{}", findCode, userCode);

                    return GenericDataResponse.ok();//"该用户账户已注销"
                } else {

                    log.info("{} 获取推广人信息 service 在用户中心查询到该账户信息，该账户状态正常 userCode:{}", findCode, userCode);

                    ManagerInfoVo result = new ManagerInfoVo();
                    result.setManagerUserCode(vo.getUserCode());
                    result.setManagerAccount(vo.getUserLoginId());
                    result.setManagerName(vo.getName());
                    result.setBranchCode(vo.getBranchCode());
                    result.setBranchName(vo.getBranchName());
                    return GenericDataResponse.okWithData(result);
                }
            } else {
                log.info("{} 获取推广人信息 service 在用户中心未查询到该账户信息，可能为普通用户 userCode:{}", findCode, userCode);
                return GenericDataResponse.ok();//"未查询到推广人信息"
            }
        } catch (Exception e) {
            e.printStackTrace();
            return GenericDataResponse.errorWithMsg("查询推广人信息异常");
        }
    }

    @Override
    public ResponseEntity<GenericListResponse<AchievementListVO>> queryAchievementList(String findCode, AchievementListQo achievementListQo) throws Exception {

        // 权限设置
        ResponseEntity<GenericDataResponse<Map<String, Object>>> responseEntity = userClient.queryUserRoleAndAuthority(achievementListQo.getUserCode(), SYS_EDU_MAN_CODE);
        LinkedHashMap<String, String> map = (LinkedHashMap) responseEntity.getBody().getData().get("dataPopedom");
        String jtBranchs = map.get("jtBranchs");
        log.debug(findCode + "用户中心返回值 jtBranchs = {}", jtBranchs);

        if (!"000000".equals(jtBranchs) && !"JT0000".equals(jtBranchs)) {//非全国

            List<String> branchCodes = new ArrayList<>();
            String[] branchs = jtBranchs.split(",");
            for (String b : branchs) {
                branchCodes.add(b);
                GenericListResponse<JtBranchInfoVo> result = userClient.queryThirdGradeBranch(b);
                if (result.getTotal() > 0) {
                    List<String> third = result.getList().stream()
                            .map(JtBranchInfoVo::getCode)
                            .collect(Collectors.toList());
                    branchCodes.addAll(third);
                }
            }

            achievementListQo.setJtBranchCodes(branchCodes);
        }
        return insClient.selectEduAchievementList(JsonUtil.object2Json(achievementListQo));
    }

    @Override
    public List<AchievementListVO> exportAchievementList(AchievementExportQo param) throws Exception {

        String findCode = "EDU_" + System.currentTimeMillis();

        // 权限设置
        ResponseEntity<GenericDataResponse<Map<String, Object>>> responseEntity = userClient.queryUserRoleAndAuthority(param.getUserCode(), SYS_EDU_MAN_CODE);
        LinkedHashMap<String, String> map = (LinkedHashMap) responseEntity.getBody().getData().get("dataPopedom");
        String jtBranchs = map.get("jtBranchs");
        log.debug(findCode + "用户中心返回值 jtBranchs = {}", jtBranchs);

        if (!"000000".equals(jtBranchs) && !"JT0000".equals(jtBranchs)) {//非全国

            List<String> branchCodes = new ArrayList<>();
            String[] branchs = jtBranchs.split(",");
            for (String b : branchs) {
                branchCodes.add(b);
                GenericListResponse<JtBranchInfoVo> result = userClient.queryThirdGradeBranch(b);
                if (result.getTotal() > 0) {
                    List<String> third = result.getList().stream()
                            .map(JtBranchInfoVo::getCode)
                            .collect(Collectors.toList());
                    branchCodes.addAll(third);
                }
            }

            param.setJtBranchCodes(branchCodes);
        }

        ResponseEntity<GenericListResponse<AchievementListVO>> result = insClient.selectEduAchievementList(JsonUtil.object2Json(param));

        return result.getBody().getList();
    }

    @Override
    public void managerEffect() {
        String findCode = "定时同步客户经理信息_" + System.currentTimeMillis();
        try {

            log.info(findCode + " 同步开始！");

            // 2.同步私保账户信息
            // 2.1查询是否第一次同步私保信息，如果第一次同步，查询当前日期以前所有信息；如果存在私保信息，则只查询当天数据
            String startDate = DateUtils.getCurrentDay() + " 00:00:00";
            String endDate = DateUtils.getCurrentDay() + " 23:59:59";

            GenericListResponse<UserManagerResultVo> pvtUserResp = userClient.queryPvtUserInfo(startDate, endDate, null);
            if (pvtUserResp.getTotal() > 0) {
                int num = updateManager(pvtUserResp.getList(), findCode);
                log.info(findCode + " 私保渠道同步个数：{}", num);
            }

            log.info(findCode + " 同步结束！");
        } catch (Exception e) {
            log.error(findCode + " 异常" + e);
        }
    }

    @Transactional
    public Integer updateManager(List<UserManagerResultVo> users, String findCode) {

        int num = 0;
        try {
            for (UserManagerResultVo user : users) {

                log.info(findCode + " 账户: {}, userCode: {}, status: {}", user.getUserLoginId(), user.getUserCode(), user.getStatus());

                String key = user.getUserCode();

                if (RedisUtil.setLock(key, "1", MANAGER_TIME_OUT)) {

                    // 1判断该客户经理是否已经存在
                    Weekend<RegisterCustomer> weekend = Weekend.of(RegisterCustomer.class);
                    WeekendCriteria<RegisterCustomer, Object> criteria = weekend.weekendCriteria();
                    criteria.andEqualTo(RegisterCustomer::getUserCode, user.getUserCode());
                    List<RegisterCustomer> managers = registerCustomerMapper.selectByExample(weekend);
                    // 1.1若存在，则更新
                    if (managers != null && managers.size() > 0) {
                        log.info(findCode + " 账户: {}, userCode: {}, status:{} 已存在，更新", user.getUserLoginId(), user.getUserCode(), user.getStatus());

                        RegisterCustomer c = new RegisterCustomer();
                        // 账户状态 = 0 ，代表停用，更新基础信息和推广关系止期
                        if ("0".equals(user.getStatus())) {
                            if (user.getUpdateTime() != null) {
                                c.setEndTime(user.getUpdateTime());
                            } else {
                                c.setEndTime(new Date());
                            }
                            c.setPromotionStatus(PromotionStatusEnum.RELIEVE.getStatus());
                        }
                        c.setManagerAccount(user.getUserLoginId());
                        c.setManagerName(user.getName());
                        c.setBranchCode(user.getBranchCode());
                        c.setBranchName(user.getBranchName());
                        if (user.getUpdateTime() != null) {
                            c.setUpdateTime(user.getUpdateTime());
                        } else {
                            c.setUpdateTime(new Date());
                        }

                        Weekend<RegisterCustomer> weekendUpd = Weekend.of(RegisterCustomer.class);
                        WeekendCriteria<RegisterCustomer, Object> criteriaUpd = weekendUpd.weekendCriteria();
                        criteriaUpd.andEqualTo(RegisterCustomer::getUserCode, user.getUserCode());
                        num += registerCustomerMapper.updateByExampleSelective(c, weekendUpd);
                        log.info(findCode + " 账户: {}, userCode: {}, status:{} 更新成功", user.getUserLoginId(), user.getUserCode(), user.getStatus());
                    }

                    // 2.判断该客户经理之前是否为普通用户并且存在上级推广人，如果存在，推广关系终止
                    Weekend<RegisterCustomer> weekend2 = Weekend.of(RegisterCustomer.class);
                    WeekendCriteria<RegisterCustomer, Object> criteria2 = weekend2.weekendCriteria();
                    criteria2.andEqualTo(RegisterCustomer::getCustomerCode, user.getUserCode());
                    criteria2.andCondition("(date_format(end_time, '%Y-%m-%d %H:%i:%s') >= '" + DateUtils.getCurrentTime() + "' or end_time is null)");
                    criteria2.andEqualTo(RegisterCustomer::getIsDeleted, false);
                    List<RegisterCustomer> managers2 = registerCustomerMapper.selectByExample(weekend2);

                    // 2.1 如果存在，则终止推广关系
                    if (managers2 != null && managers2.size() > 0) {
                        RegisterCustomer c = new RegisterCustomer();
                        if (user.getUpdateTime() != null) {
                            c.setEndTime(user.getUpdateTime());
                            c.setUpdateTime(user.getUpdateTime());
                        } else {
                            c.setEndTime(new Date());
                            c.setUpdateTime(new Date());
                        }
                        c.setPromotionStatus(PromotionStatusEnum.RELIEVE.getStatus());
                        Weekend<RegisterCustomer> weekend3 = Weekend.of(RegisterCustomer.class);
                        WeekendCriteria<RegisterCustomer, Object> criteria3 = weekend3.weekendCriteria();
                        criteria3.andEqualTo(RegisterCustomer::getCustomerCode, user.getUserCode());
                        num += registerCustomerMapper.updateByExampleSelective(c, weekend3);
                        log.info(findCode + " 账户: {}, userCode: {}, status:{} 为外部用户转内部用户且存在上级推广人，终止推广关系成功", user.getUserLoginId(), user.getUserCode(), user.getStatus());
                    }
                } else {
                    log.info(findCode + " 账户: {}, userCode: {}, key: {} 未失效", user.getUserLoginId(), user.getUserCode(), key);
                }
            }
        } catch (Exception e) {
            log.error(findCode + " 同步时异常" + e);
        }
        return num;
    }

    //内部人员配置接口
    @Override
    public ResponseEntity setManager(String findCode, RegisterCustomer registerCustomer, String level) {
        try {

            log.info("{} 内部人员配置接口 service 开始", findCode);

            //判断传入参数是否完整
            if (StringUtils.isBlank(registerCustomer.getUserCode())) {
                return GenericDataResponse.errorWithMsg("参数传入不完整");
            }

            if (StringUtils.isNotBlank(registerCustomer.getBranchCode())
                    && StringUtils.isNotBlank(level)
                    && ("03".equals(level) || "05".equals(level))) {
                // 有分支机构编码，现为内部人员

                log.info("{} 内部人员配置接口 service 该用户有分支机构，现为内部人员 userCode->{},branchCode->{},branchName->{}",
                        findCode, registerCustomer.getUserCode(), registerCustomer.getBranchCode(), registerCustomer.getBranchName());

                if (StringUtils.isBlank(registerCustomer.getCustomerAccount())) {
                    //有关系且有没有被推广人时 状态为初始化
                    registerCustomer.setPromotionStatus(PromotionStatusEnum.INIT.getStatus());
                } else {
                    //有关系且有被推广人时 状态为正常
                    registerCustomer.setPromotionStatus(PromotionStatusEnum.NORMAL.getStatus());
                }
                //判断该用户是否存在作为推广人的推广关系，存在->更新信息；
                //判断该用户是否存在作为被推广人的推广关系，存在->终止；
                //不存在->插入推广人新记录
                Weekend<RegisterCustomer> weekend = Weekend.of(RegisterCustomer.class);
                WeekendCriteria<RegisterCustomer, Object> criteria = weekend.weekendCriteria();
                criteria.andEqualTo(RegisterCustomer::getUserCode, registerCustomer.getUserCode());
                criteria.andEqualTo(RegisterCustomer::getIsDeleted, false);
                criteria.andCondition("(date_format(end_time, '%Y-%m-%d %H:%i:%s') >= '" + DateUtils.getCurrentTime() + "' or end_time is null)");

                List<RegisterCustomer> customers = registerCustomerMapper.selectByExample(weekend);

                log.info("{} 内部人员配置接口 service 将该用户作为推广人进行查询 result->{}", findCode, JsonUtil.object2Json(customers));
                if (customers != null && customers.size() > 0) {
                    int num = registerCustomerMapper.updateByExampleSelective(registerCustomer, weekend);
                    log.info("{} 内部人员配置接口 service 该用户存在作为推广人的有效推广关系 更新基本信息 共更新记录数->{}", findCode, num);

                } else {

                    log.info("{} 内部人员配置接口 service 该用户不存在作为推广人的有效推广关系", findCode);

                    Weekend<RegisterCustomer> cusWeekend = Weekend.of(RegisterCustomer.class);
                    WeekendCriteria<RegisterCustomer, Object> cusCriteria = cusWeekend.weekendCriteria();
                    cusCriteria.andEqualTo(RegisterCustomer::getCustomerCode, registerCustomer.getUserCode());
                    cusCriteria.andEqualTo(RegisterCustomer::getIsDeleted, false);
                    cusCriteria.andCondition("(date_format(end_time, '%Y-%m-%d %H:%i:%s') >= '" + DateUtils.getCurrentTime() + "' or end_time is null)");

                    customers = registerCustomerMapper.selectByExample(cusWeekend);

                    log.info("{} 内部人员配置接口 service 将该用户作为被推广人进行查询 result->{}", findCode, JsonUtil.object2Json(customers));

                    if (customers != null && customers.size() > 0) {

                        log.info("{} 内部人员配置接口 service 该用户作为被推广人存在有效推广关系", findCode);

                        RegisterCustomer c = new RegisterCustomer();
                        c.setUpdateTime(new Date());
                        c.setEndTime(new Date());
                        //添加关系解除
                        c.setPromotionStatus(PromotionStatusEnum.RELIEVE.getStatus());

                        registerCustomerMapper.updateByExampleSelective(c, cusWeekend);

                        log.info("{} 内部人员配置接口 service 该用户作为被推广人的推广关系终止 因为该用户目前存在分支机构编码 branchCode->{},branchName->{}",
                                findCode, registerCustomer.getBranchCode(), registerCustomer.getBranchName());

                        //添加到数据库
                        registerCustomer.setStartTime(new Date());
                        registerCustomer.setCreationTime(new Date());
                        registerCustomer.setIsDeleted(false);
                        registerCustomerMapper.insertSelective(registerCustomer);

                        log.info("{} 内部人员配置接口 service 该用户作为推广人 保存成功", findCode);
                    } else {

                        log.info("{} 内部人员配置接口 service 该用户不存在作为被推广人的有效推广关系", findCode);
                        //添加到数据库
                        registerCustomer.setStartTime(new Date());
                        registerCustomer.setCreationTime(new Date());
                        registerCustomer.setIsDeleted(false);
                        registerCustomerMapper.insertSelective(registerCustomer);

                        log.info("{} 内部人员配置接口 service 该用户作为推广人 保存成功", findCode);
                    }
                }

            } else {// 没有分支机构编码，现为外部人员

                log.info("{} 内部人员配置接口 service 该用户没有分支机构，现为外部人员 userCode->{},branchCode->{},branchName->{}",
                        findCode, registerCustomer.getUserCode(), registerCustomer.getBranchCode(), registerCustomer.getBranchName());

                //将该用户作为推广人的推广关系终止
                Weekend<RegisterCustomer> weekend = Weekend.of(RegisterCustomer.class);
                WeekendCriteria<RegisterCustomer, Object> criteria = weekend.weekendCriteria();
                criteria.andEqualTo(RegisterCustomer::getUserCode, registerCustomer.getUserCode());
                criteria.andEqualTo(RegisterCustomer::getIsDeleted, false);
                criteria.andCondition("(date_format(end_time, '%Y-%m-%d %H:%i:%s') >= '" + DateUtils.getCurrentTime() + "' or end_time is null)");

                RegisterCustomer c = new RegisterCustomer();
                c.setUpdateTime(new Date());
                c.setEndTime(new Date());
                //解除推广关系
                c.setPromotionStatus(PromotionStatusEnum.RELIEVE.getStatus());
                int num = registerCustomerMapper.updateByExampleSelective(c, weekend);

                log.info("{} 内部人员配置接口 service 该用户作为推广人的有效推广关系终止 因为该用户目前不存在分支机构 共更新记录数->{}", findCode, num);
            }

            return GenericDataResponse.okWithData("配置内外部人员成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.info("{} 内部人员配置接口 异常->{}", findCode, e);
        }

        return GenericDataResponse.errorWithMsg("配置内外部人员异常");
    }

    @Override
    @Transactional
    public ResponseEntity<GenericDataResponse<PromotersVo>> queryPromotersByEmployeeNum(String findCode, String employeeNum) {
        //用户中心查询
        try {
            GenericDataResponse<EmployeeVO> response = userClient.selectByEmployeeNum(employeeNum);
            if (null == response
                    || GenericDataResponse.CODE_NG.equals(response.getCode())
                    || null == response.getData()) {
                return GenericDataResponse.errorWithMsg("无查询结果!", PromotersVo.class);
            }
            //员工信息 to 推广人信息
            PromotersVo promotersVo = new PromotersVo(response.getData());

            //添加推荐人的营销模式及推广关系状态
            MarketerInfoQO marketerInfoQO = new MarketerInfoQO();
            marketerInfoQO.setMarketerNo(promotersVo.getUserCode());
            List<MarketerInfoEntity> marketerInfoEntities = marketerInfoService.queryMarketerList(findCode, marketerInfoQO, false);
            if (marketerInfoEntities.size() > 0) {
                MarketerInfoEntity marketerInfo = marketerInfoEntities.get(0);
                promotersVo.setChannelCode(marketerInfo.getChannelCode());
                promotersVo.setChannelName(marketerInfo.getChannelName());
                promotersVo.setAddChannelCode(marketerInfo.getAddChannelCode());
                promotersVo.setAddChannelName(marketerInfo.getAddChannelName());
            }
            return GenericDataResponse.okWithData(promotersVo);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("{}通过员工编号:{}查询推广人相关信息异常!", findCode, employeeNum);
        }
        return GenericDataResponse.errorWithMsg("无查询结果!", PromotersVo.class);
    }

    @Override
    public int removePromotionById(String findCode, Integer id, boolean isDeleted) {
        log.info("{} 推广人的有效推广关系终止id:{}", findCode, id);
        RegisterCustomer registerCustomer = new RegisterCustomer();
        registerCustomer.setId(id);
        registerCustomer.setUpdateTime(new Date());
        registerCustomer.setPromotionStatus(PromotionStatusEnum.RELIEVE.getStatus());
        registerCustomer.setEndTime(new Date());
        registerCustomer.setIsDeleted(isDeleted);
        return registerCustomerMapper.updateByPrimaryKeySelective(registerCustomer);
    }

    /**
     * 解除关系
     *
     * @param findCode
     * @return
     */
    private int removePromotion(String findCode, String userCode, String customerCode) {
        log.info("{} 推广人的有效推广关系终止:入参userCode:{},customerCode", findCode, userCode, customerCode);
        if (StringUtils.isBlank(userCode) &&
                StringUtils.isBlank(customerCode)) {
            log.info("{} 推广人的有效推广关系终止出错，入参推广人及被推广人不能同时为空!", findCode);
            return 0;
        }
        Weekend<RegisterCustomer> weekend = Weekend.of(RegisterCustomer.class);
        WeekendCriteria<RegisterCustomer, Object> criteria = weekend.weekendCriteria();
        criteria.andIn(RegisterCustomer::getPromotionStatus,
                Lists.newArrayList(PromotionStatusEnum.INIT.getStatus(), PromotionStatusEnum.NORMAL.getStatus()));
        if (StringUtils.isNotBlank(userCode)) {
            criteria.andEqualTo(RegisterCustomer::getUserCode, userCode);
        }
        if (StringUtils.isNotBlank(customerCode)) {
            criteria.andEqualTo(RegisterCustomer::getCustomerCode, customerCode);
        }
        criteria.andEqualTo(RegisterCustomer::getIsDeleted, false);

        RegisterCustomer registerCustomer = new RegisterCustomer();
        registerCustomer.setUpdateTime(new Date());
        registerCustomer.setPromotionStatus(PromotionStatusEnum.RELIEVE.getStatus());
        registerCustomer.setEndTime(new Date());
        return registerCustomerMapper.updateByExampleSelective(registerCustomer, weekend);
    }

    @Override
    public ResponseEntity transferPromotionById(String findCode, RegisterCustomer registerCustomer) {
        if (null == registerCustomer ||
                null == registerCustomer.getId() ||
                StringUtils.isBlank(registerCustomer.getUserCode()) ||
                StringUtils.isBlank(registerCustomer.getCustomerCode())) {
            log.info("{} 推广人关系转移参数不全!入参：{}", findCode, JSON.toJSONString(registerCustomer));
            return GenericDataResponse.errorWithMsg("推广人关系转移参数不全!");
        }
        //检查推广人是否合法
        RegisterCustomer registerCustomerQo = new RegisterCustomer();
        registerCustomerQo.setUserCode(registerCustomer.getUserCode());
        registerCustomerQo.setBranchCode(registerCustomer.getBranchCode());

        ResponseEntity<GenericDataResponse<RegisterCustomer>> checkValue = checkValidity(findCode, registerCustomerQo);
        if (GenericResponse.CODE_OK.equals(checkValue.getBody().getCode())) {
            //移除并删除关系
            removePromotionById(findCode, registerCustomer.getId(), true);
            //添加新的关系
            insertBinaryRegisterCustomer(findCode, registerCustomer);
            return GenericDataResponse.ok();
        }
        return GenericDataResponse.errorWithMsg("推广人关系转移不成功, 推广人不是公司员工!");
    }


    /**
     * 检查并处理有效性
     *
     * @param registerCustomer
     * @return false表示该推广关系不合法 推广人 不能做为推广人
     */
    @Override
    public ResponseEntity<GenericDataResponse<RegisterCustomer>> checkValidity(String findCode, RegisterCustomer registerCustomer) {
        if (null == registerCustomer || StringUtils.isBlank(registerCustomer.getUserCode())) {
            log.info("{} 推广人信息不全!入参：{}", findCode, JSON.toJSONString(registerCustomer));
            return GenericDataResponse.errorWithMsg("推广人信息不全!", RegisterCustomer.class);
        }
        //如果推广人与被推广人同一个人不检查被推广人
        if (registerCustomer.getUserCode().equals(registerCustomer.getCustomerCode())) {
            registerCustomer.setCustomerCode(null);
        }

        //查询用户中心该推广人是否 可以当符合推广人
        ResponseEntity<GenericDataResponse<LoginResultVO>> userResponse = userClient.queryInfoByUserCode(registerCustomer.getUserCode(), SYS_EDU_PC_CODE);
        log.info("{}用户中心查询推广人基本信息 userResponse：{}", findCode, JsonUtil.object2Json(userResponse));
        if (null == userResponse) {
            return GenericDataResponse.errorWithMsg("查询推广人信息失败!", RegisterCustomer.class);
        }

        LoginResultVO userInfo = userResponse.getBody().getData();
        log.info("{}用户中心查询推广人基本信息 userInfo：{}", findCode, JsonUtil.object2Json(userInfo));

        if (!isEmployee(userInfo)) {
            log.info("{}推广人不是公司员工，不能做推广人!入参：{}", findCode, JSON.toJSONString(registerCustomer));
            //解除 该推广人的所有[推广]关系
            removePromotion(findCode, registerCustomer.getUserCode(), null);
            return GenericDataResponse.errorWithMsg("推广人不是公司员工，不能做推广人!", RegisterCustomer.class);
        }
        //检验该推广人是否存在[被推广]的记录如果有解除关系
        removePromotion(findCode, null, registerCustomer.getUserCode());
        //更新推广人最新用户信息
        registerCustomer.setBranchCode(userInfo.getBranchCode());
        registerCustomer.setBranchName(userInfo.getBranchName());
        registerCustomer.setManagerName(userInfo.getUserName());
        registerCustomer.setManagerAccount(userInfo.getLoginAccount());

        //如果被推广人有值
        if (StringUtils.isNotBlank(registerCustomer.getCustomerCode())) {
            //查询用户中心该被推广人是否 可以当符合被推广人
            ResponseEntity<GenericDataResponse<LoginResultVO>> customerResponse = userClient.queryInfoByUserCode(registerCustomer.getCustomerCode(), SYS_EDU_PC_CODE);
            if (null == customerResponse) {
                return GenericDataResponse.errorWithMsg("查询被推广人信息失败!", RegisterCustomer.class);
            }
            if (GenericDataResponse.CODE_NG.equals(customerResponse.getBody().getCode())) {
                return GenericDataResponse.errorWithMsg("被推广人：" + customerResponse.getBody().getMsg(), RegisterCustomer.class);
            }
            LoginResultVO customerInfo = customerResponse.getBody().getData();
            if (isEmployee(customerInfo)) {
                log.info("{}被推广人是公司员工，不能成为被推广人!入参：{}", findCode, JSON.toJSONString(registerCustomer));
                //解除 该被推广人的被推广关系
                removePromotion(findCode, null, registerCustomer.getCustomerCode());
                return GenericDataResponse.errorWithMsg("被推广人是公司员工，不能成为被推广人!", RegisterCustomer.class);
            }
            //已与胡懿桐确认只要当前用户没有 有效的推广关系就可以再次被推广
            //检验该被推广人是否存在被推广的记录，如果有就返回false，如果没有被推广记录 表示可以被推广
            RegisterCustomer registerCustomerQo = new RegisterCustomer();
            registerCustomerQo.setCustomerCode(registerCustomer.getCustomerCode());
            registerCustomerQo.setPromotionStatus(PromotionStatusEnum.NORMAL.getStatus());
            registerCustomerQo.setIsDeleted(false);
            if (registerCustomerMapper.selectCount(registerCustomerQo) > 0) {
                return GenericDataResponse.errorWithMsg("被推广人已存在有效的推广关系，不能再次做为被推广人!", RegisterCustomer.class);
            }
            //更新被推广人信息
            registerCustomer.setCustomerAccount(customerInfo.getLoginAccount());
            registerCustomer.setCustomerName(customerInfo.getUserName());
        }
        return GenericDataResponse.okWithData(registerCustomer);
    }

    @Override
    public ResponseEntity<GenericDataResponse<ManagerInfoVo>> queryPromoterByCustomerAccount(String findCode, String customerAccount) {
        try {
            ResponseEntity<GenericDataResponse<Map<String, Object>>> edu = userClient.queryPersonalUserAuthenInfo(customerAccount, "edu");
            GenericDataResponse<Map<String, Object>> remoteMap = edu.getBody();
            Map<String, Object> data = remoteMap.getData();
            if (data != null) {
                String holderCode = (String) data.get("userCode");
                log.info("{}通过帐号:{} 查询userCode：{}", findCode, customerAccount, holderCode);
                return queryPromotersInfo(findCode, holderCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("{}通过帐号:{},查询推广人异常", findCode, e);
        }
        return GenericDataResponse.okWithData(null);
    }

    @Override
    public ResponseEntity policyAgent(MultipartFile excelFile) {
        String findCode = "policyAgent_" + System.currentTimeMillis();
        //清单解析结果
        ParserResultPolicyAgentVo parserResultVo;
        try {
            ResponseEntity<GenericDataResponse<ParserResultPolicyAgentVo>> responseEntity =
                    parserClient.policyAgentAnalysisExcelByFile(excelFile, POLICY_AGENT_MODEL, ReturnType.DETAIL, SaveType.NONE, CHANNEL_CODE);
            List<String> errorMsgList = Lists.newArrayList();
//            ParserResultPolicyAgentVo parserResultPolicyAgentVo = checkResponse(responseEntity, errorMsgList);
            //清单解析的错误集合
            //如果清单解析的结果 有错误信息  直接返回报错
            if ((parserResultVo = checkResponse(responseEntity, errorMsgList)) == null) {
                return GenericDataResponse.errorWithMsg(JSON.toJSONString(errorMsgList));
            }

        } catch (Exception e) {
            return GenericDataResponse.errorWithMsg("清单解析出错!");
        }

        StringBuffer errorMsg = new StringBuffer();
        List<PolicyAgentVo> datas = parserResultVo.getDatas();
        for (PolicyAgentVo policyAgentVo : datas) {
            //通过帐号查询该帐号是否在推广关系表中有记录
            RegisterCustomer registerCustomer = new RegisterCustomer();
            registerCustomer.setManagerAccount(policyAgentVo.getManagerAccount());
            List<RegisterCustomer> registerCustomers = registerCustomerMapper.select(registerCustomer);
            if (CollectionUtils.isEmpty(registerCustomers)) {
                String errMsg = String.format("%s投保单号为：%s的推广人帐号：%s，在推广人关系中无记录。", findCode, policyAgentVo.getAppCode(), policyAgentVo.getManagerAccount());
                log.info("{},{}", findCode, errMsg);
                errorMsg.append(errMsg);
                continue;
            }
            //绑定推广人
            List<PolicyAgentDto> policyAgentDto = createPolicyAgentDtos(policyAgentVo, registerCustomers.get(registerCustomers.size() - 1));
            try {
                GenericDataResponse response = insOrderClient.policyAgents(JSON.toJSONString(policyAgentDto), policyAgentVo.getAppCode());
                log.info("{},调用投保中心修改结果为{}", findCode, JSON.toJSONString(response));
                if (response.getCode().equals(GenericDataResponse.CODE_NG)) {
                    String errMsg = String.format("投保单号为：%s的推广人帐号：%s，调用投保中心绑定推广人失败。", policyAgentVo.getAppCode(), policyAgentVo.getManagerAccount());
                    log.info(errMsg);
                    errorMsg.append(errMsg);
                }
            } catch (Exception e) {
                String errMsg = String.format("投保单号为：%s的推广人帐号：%s，调用投保中心绑定推广人失败。", policyAgentVo.getAppCode(), policyAgentVo.getManagerAccount());
                log.error(errMsg, e);
                errorMsg.append(errMsg);
                continue;
            }
        }

        return errorMsg.length() == 0 ? GenericDataResponse.ok() : GenericDataResponse.errorWithMsg(errorMsg.toString());
    }

    private List<PolicyAgentDto> createPolicyAgentDtos(PolicyAgentVo policyAgentVo, RegisterCustomer registerCustomer) {
        PolicyAgentDto policyAgentDto = new PolicyAgentDto();
        policyAgentDto.setAgentCode(registerCustomer.getUserCode());
        policyAgentDto.setAgentName(policyAgentVo.getManagerName());
        policyAgentDto.setBranchCode(registerCustomer.getBranchCode());
        policyAgentDto.setBranchName(registerCustomer.getBranchName());
        policyAgentDto.setDepartCode(policyAgentVo.getManagerAccount());
        return Lists.newArrayList(policyAgentDto);
    }

    /**
     * 处理接口返回结果
     */
    private ParserResultPolicyAgentVo checkResponse(ResponseEntity<GenericDataResponse<ParserResultPolicyAgentVo>> responseEntity, List<String> errorMsgList) {
        ParserResultPolicyAgentVo data;
        if (null == responseEntity.getBody() || (data = responseEntity.getBody().getData()) == null) {
            if (responseEntity.getBody().getMsg() != null) {
                errorMsgList.add(responseEntity.getBody().getMsg());
            } else {
                errorMsgList.add("调用清单解析-上传清单接口失败");
            }
            return null;
        }

        // 接口正常返回错误信息，添加到errorMsgList
        List<Map<String, String>> errorMessages = data.getErrorMessages();
        if (CollectionUtils.isNotEmpty(errorMessages)) {
            for (Map<String, String> errorMessage : errorMessages) {
                String row = errorMessage.get("row");
//                String column = errorMessage.get("column");
                String error = errorMessage.get("errorMessage");
                StringBuilder errorMsg = new StringBuilder();
                if (Integer.valueOf(row) != 0) {
                    errorMsg.append("第").append(row).append("行,");
                }
                errorMsg.append("（").append(error).append("）");
                errorMsgList.add(String.valueOf(errorMsg));
            }
            return null;
        }
        return data;
    }

    /**
     * 判断是否是员工(内部，外部)
     *
     * @param userInfo
     * @return
     */
    private boolean isEmployee(LoginResultVO userInfo) {
        return null != userInfo
                && StringUtils.isNotBlank(userInfo.getBranchCode())
                && StringUtils.isNotBlank(userInfo.getLevel())
                && ("03".equals(userInfo.getLevel()) || "05".equals(userInfo.getLevel()));
    }


}
